package com.starsoft.quant.strategy.bank;

import java.util.Date;
import java.util.List;

import com.starsoft.frame.util.DateUtil;

public class RoeCalculate {

	public double getRoe(List<Cashflow> cashIn, Cashflow cashOut){
		for (int i = 0; i < cashIn.size(); i++) {
			Cashflow cashflow = cashIn.get(i);
			Double years = DateUtil.getYears(cashflow.getDate(), cashOut.getDate());
			if (years < 0) {
				throw new RuntimeException("error Date input");
			}
			cashflow.setTimeToEnd(years);
		}
		Double ratioA = null;
		Double ratioB = null;
		Double ratio = 0.1;
		while (ratioA == null || ratioB == null) {
			double cashOutTemp = this.caculateFV(cashIn, ratio, cashOut.getFactor());
			if (cashOutTemp > cashOut.getAmount()) {
				ratioB = ratio;
				ratio -= 0.05;
			} else if (cashOutTemp < cashOut.getAmount()) {
				ratioA = ratio;
				ratio += 0.05;
			}
		}
		for (int i = 0; i < 20; i++) {
			ratio = (ratioA + ratioB) / 2;
			double cashOutTemp = this.caculateFV(cashIn, ratio, cashOut.getFactor());
			if (Math.abs(cashOutTemp / cashOut.getAmount() - 1) < 0.00001) {
				break;
			} else if (cashOutTemp > cashOut.getAmount()) {
				ratioB = ratio;
			} else if (cashOutTemp < cashOut.getAmount()) {
				ratioA = ratio;
			}
		}
		return ratio;
	}

	public double caculateFV(List<Cashflow> cashIn, double ratio, double factor) {
		double cashOut = 0;
		for (int i = 0; i < cashIn.size(); i++) {
			double adjRaio = Math.pow(1 + ratio, cashIn.get(i).getTimeToEnd());
			cashOut += adjRaio * cashIn.get(i).getAmount()* cashIn.get(i).getFactor();
		}
		return cashOut/factor;
	}
	
	public double caculateFV(List<Cashflow> cashIn, double ratio, double factor, Date futureDate) {
		for (int i = 0; i < cashIn.size(); i++) {
			Cashflow cashflow = cashIn.get(i);
			Double years = DateUtil.getYears(cashflow.getDate(), futureDate);
			if (years < 0) {
				throw new RuntimeException("error Date input");
			}
			cashflow.setTimeToEnd(years);
		}
		return this.caculateFV(cashIn, ratio, factor);
	}
}
